#include "Runtime/BattleFirePrefix.h"
#include "CGIOpenGL.h"
#include "Runtime/Log/Logger.h"

void InitializeOGL() {
}
void CheckLastOpenGLError(const char* inFile, long inLine, const char*inGLCall){
    GLenum lastError = glGetError();
    if(lastError==GL_NO_ERROR)
    {
        return ;
    }
    switch (lastError){
    case GL_INVALID_VALUE:
        //Debug("%s GL_INVALID_VALUE", inGLCall);
        break;
    default:
        //Debug("GLError[0x%x] file[%s:%d] [%s]", (int)lastError,inFile,inLine,inGLCall);
        break;
    }
}

namespace Alice
{
    GLuint CGIOpenGL::CompileShader(GLenum inShaderType, const char* inShaderCode)
    {
        GLuint shader = 0;
        OGL_CALL(shader = glCreateShader(inShaderType));
        OGL_CALL(glShaderSource(shader, 1, &inShaderCode, nullptr));
        OGL_CALL(glCompileShader(shader));
        GLint compileResult = GL_TRUE;
        OGL_CALL(glGetShaderiv(shader, GL_COMPILE_STATUS, &compileResult));
        if (compileResult == GL_FALSE) {
            char szLog[10240] = { 0 };
            GLsizei logLen = 0;
            OGL_CALL(glGetShaderInfoLog(shader, 10240, &logLen, szLog));
            //Debug("Compile Shader fail error log : %s \nshader code :\n%s\n", szLog, inShaderCode);
            OGL_CALL(glDeleteShader(shader));
            shader = 0;
        }
        return shader;
    }

    GLuint CGIOpenGL::CreateProgram(GLenum* inShaders, size_t inShaderCount)
    {
        GLuint program = 0;
        OGL_CALL(program=glCreateProgram());
        for(size_t i = 0;i<inShaderCount;i++)
        {
            OGL_CALL(glAttachShader(program, inShaders[i]));
        }
        OGL_CALL(glLinkProgram(program));
        for(size_t i = 0;i<inShaderCount;i++)
        {
            OGL_CALL(glDetachShader(program, inShaders[i]));
        }
        GLint nResult;
        OGL_CALL(glGetProgramiv(program, GL_LINK_STATUS, &nResult));
        if (nResult == GL_FALSE) {
            char log[10240] = { 0 };
            GLsizei writed = 0;
            OGL_CALL(glGetProgramInfoLog(program, 10240, &writed, log));
            //Debug("create gpu program fail,link error : %s\n", log);
            OGL_CALL(glDeleteProgram(program));
            program = 0;
        }
        return program;
    }
    GLuint CGIOpenGL::CreateBufferObject(GLenum inType,const void*inData,int inSize,GLenum inUsage)
    {
        GLuint buffer;
        OGL_CALL(glGenBuffers(1, &buffer));
        OGL_CALL(glBindBuffer(inType, buffer));
        OGL_CALL(glBufferData(inType, inSize, inData, inUsage));
        OGL_CALL(glBindBuffer(inType, 0));
        return buffer;
    }
    GLuint CGIOpenGL::CreateFrameBufferObject(GLuint*inColorRTs,GLenum*inColorRTAttachments,int inColorRTCount,GLuint inDSRT)
    {
        GLuint fbo;
        glGenFramebuffers(1, &fbo);
        glBindFramebuffer(GL_FRAMEBUFFER, fbo);
        for(int i=0;i<inColorRTCount;i++)
        {
            glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0+i, GL_TEXTURE_2D, inColorRTs[i], 0);
            inColorRTAttachments[i]=GL_COLOR_ATTACHMENT0+i;
        }
        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, inDSRT, 0);
        glDrawBuffers(inColorRTCount, inColorRTAttachments);
        glBindFramebuffer(GL_FRAMEBUFFER, 0);
        return fbo;
    }


}
